<?php

declare(strict_types=1);

namespace App\Common\Service;

use App\Common\Interfaces\TencentMapInterface;
use App\Setting\Service\SettingConfigService;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\RequestOptions;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\Redis\Redis;
use Mine\Helper\Ip2region;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class TencentMapService implements TencentMapInterface
{
    /**
     * 腾讯地图key
     * @var string
     */
    protected string $appKey;

    /**
     * 腾讯地图url
     * @var string
     */
    protected string $url = 'https://apis.map.qq.com/ws/geocoder/v1';

    /**
     * 系统配置
     * @var SettingConfigService
     */
    protected SettingConfigService $configService;

    /**
     * @var Client
     */
    protected Client $client;

    protected Redis $redis;

    public function __construct(SettingConfigService $configService,ClientFactory $clientFactory,Redis $redis)
    {
        $this->configService = $configService;
        $keys =  $this->configService->getConfigByKey('tencent_api_key')['value'] ?? 'BOPBZ-4UNCP-KTWDK-VD4MB-76E5V-7WFLE';
        $keysArr = explode(',',$keys);
        $this->appKey = $keysArr[array_rand($keysArr)];
        $this->client = $clientFactory->create();
        $this->redis = $redis;
    }

    public function getCityInfoByIp(string $ip): mixed
    {
        $cacheName = 'ch_get_city_info_ip:'.$ip;
        $cityInfo = $this->redis->get($cacheName);
        if(empty($cityInfo)){
            $cityInfo = [
                'province' => '',
                'city' => '',
                'area' => '',
                'lat' => '',
                'lng' => '',
            ];
            try {
                $response = $this->client->get('https://apis.map.qq.com/ws/location/v1/ip', [
                    RequestOptions::QUERY => [
                        'ip' => $ip,
                        'key' => $this->appKey
                    ],
                    'timeout' => 10,
                ]);
                $result = json_decode($response->getBody()->getContents(),true);
                $pattern = '/(?:省|市|区)/u';
                if($result['status'] == 0){
                    $location = $result['result']['location'];
                    $region = $result['result']['ad_info'];
                    $cityInfo = [
                        'province' => preg_replace($pattern, '', $region['province']),
                        'city' => preg_replace($pattern, '', $region['city']),
                        'area' =>  preg_replace($pattern, '', $region['district']),
                        'lat' => $location['lat'],
                        'lng' => $location['lng'],
                    ];
                }else{
                    $info = (new \App\Common\Helpers\Ip2Region())->searchByIp($ip);
                    $cityInfo = [
                        'province' => preg_replace($pattern, '', $info['province']),
                        'city' => preg_replace($pattern, '', $info['city']),
                        'area' =>  '',
                        'lat' => '',
                        'lng' => '',
                    ];
                }
            } catch (GuzzleException $e) {
                logger()->info($e->getMessage());
            }

            $this->redis->set($cacheName,$cityInfo,60 * 60 * 24);
        }
        return $cityInfo;
    }
}